package com.ryskoo.catering.productmain.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ryskoo.catering.ordermain.service.IOrderMainService;
import com.ryskoo.catering.productattr.domain.ProductAttrPO;
import com.ryskoo.catering.productattr.service.IProductAttrService;
import com.ryskoo.catering.productattrvalue.domain.ProductAttrValuePO;
import com.ryskoo.catering.productattrvalue.service.IProductAttrValueService;
import com.ryskoo.catering.productcate.domain.ProductCategoryPO;
import com.ryskoo.catering.productcate.service.IProductCategoryService;
import com.ryskoo.catering.productimage.domain.ProductImagePO;
import com.ryskoo.catering.productimage.service.IProductImageService;
import com.ryskoo.catering.productmain.domain.ProductMainPO;
import com.ryskoo.catering.productmain.repository.IProductMainRepository;
import com.ryskoo.catering.productspec.domain.ProductSpecPO;
import com.ryskoo.catering.productspec.service.IProductSpecService;
import com.ryskoo.catering.producttemplateattr.domain.ProductTemplateAttrPO;
import com.ryskoo.catering.producttemplateattr.service.IProductTemplateAttrService;
import com.ryskoo.catering.vendortemplaterel.domain.VendorTemplateRelPO;
import com.ryskoo.catering.vendortemplaterel.service.IVendorTemplateRelService;
import com.ryskoo.catering.vendortemplatereldetail.domain.VendorTemplateRelDetailPO;
import com.ryskoo.catering.vendortemplatereldetail.service.IVendorTemplateRelDetailService;
import com.ryskoo.common.constant.EurekaServiceName;
import com.ryskoo.customer.vendor.domain.VendorPO;
import com.ryskoo.customer.vendor.service.IVendorService;
import com.ryskoo.framework.core.bean.QueryMessageDTO;
import com.ryskoo.framework.core.service.BasicServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class ProductMainServiceImpl extends BasicServiceImpl<ProductMainPO> implements IProductMainService {
    private static final Logger logger = LogManager.getLogger(EurekaServiceName.CATERING_SERVICE);

    @Autowired
    private IProductMainRepository productRepository;
    @Autowired
    private IProductSpecService productSpecService;
    @Autowired
    private IProductAttrService productAttrService;
    @Autowired
    private IProductAttrValueService productAttrValueService;
    @Autowired
    private IVendorTemplateRelService vendorTemplateRelService;
    @Autowired
    private IVendorTemplateRelDetailService vendorTemplateRelDetailService;
    @Autowired
    private IProductTemplateAttrService productTemplateAttrService;
    @Autowired
    private IProductCategoryService productCategoryService;
    @Autowired
    private IProductImageService productImageService;
    @Autowired
    @Lazy
    private IOrderMainService orderMainService;
    @Autowired
    private IVendorService vendorService;

    @PostConstruct
    public void init() {
        this.setDao(productRepository);
    }

    @Override
    public void onShelves(List<String> idList) {
        productRepository.onShelves(idList);
    }

    @Override
    public void offShelves(List<String> idList) {
        productRepository.offShelves(idList);
    }

    @Override
    public void sellOut(List<String> idList) {
        productRepository.sellOut(idList);
    }

    @Override
    public void supply(List<String> idList) {
        productRepository.supply(idList);
    }

    @Override
    public List<String> getUuidsByCategoryId(String categoryUuid) {
        return productRepository.getUuidsByCategoryId(categoryUuid);
    }

    @Override
    public ProductMainPO toEdit(String uuid) {
        ProductMainPO productMainPO = productRepository.getByUuid(uuid);
        // 属性集合，用于展示在PC后台菜品编辑页面
        List<ProductAttrPO> attrs = productAttrService.getAttrsByMainUuid(uuid);
        // 过滤出规格属性集合，用于展示在商户端APP菜品编辑页面
        List<ProductAttrPO> specAttrs = attrs.stream().filter(attr -> attr.isSpec()).collect(Collectors.toList());
        // 过滤出非规格属性集合，用于展示在商户端APP菜品编辑页面
        List<ProductAttrPO> noSpecAttrs = attrs.stream().filter(attr -> !attr.isSpec()).collect(Collectors.toList());
        productMainPO.setAttrsJson(JSONArray.toJSONString(attrs));
        //List<String> attrNames = attrs.stream().map(ProductAttrPO::getName).collect(Collectors.toList());
        List<String> attrUuids = attrs.stream().map(ProductAttrPO::getTemplateAttrUuid).collect(Collectors.toList());
        String vendorUuid = productMainPO.getVendorUuid();
        // 获取关联的属性模板（将未启用的属性模板展示出来）
        List<String> relUuids = vendorTemplateRelService.getUuidsByVendorUuid(vendorUuid);
        //List<String> attrNames2 = new ArrayList<>();
        List<String> attrUuids2 = new ArrayList<>();
        for (String relUuid : relUuids) {
            VendorTemplateRelPO vendorTemplateRelPO = vendorTemplateRelService.getByUuid(relUuid);
            ProductTemplateAttrPO attr = productTemplateAttrService.getByUuid(vendorTemplateRelPO.getTemplateAttrUuid());
            attrUuids2.add(attr.getUuid());
            //if(!attrNames.contains(attr.getName())){
            if (!attrUuids.contains(attr.getUuid())) {
                ProductAttrPO productAttrPO = new ProductAttrPO();
                productAttrPO.setTemplateAttrUuid(attr.getUuid());
                productAttrPO.setName(attr.getName());
                productAttrPO.setSpec(attr.isSpec());
                productAttrPO.setStatus(false);
                List<VendorTemplateRelDetailPO> details = vendorTemplateRelDetailService.getByMainUuid(relUuid, true, true);
                List<ProductAttrValuePO> valueList = new ArrayList<>();
                for (VendorTemplateRelDetailPO detail : details) {
                    if (detail.isStatus()) {
                        ProductAttrValuePO productAttrValuePO = new ProductAttrValuePO();
                        productAttrValuePO.setTemplateAttrValueUuid(detail.getValueUuid());
                        productAttrValuePO.setValue(detail.getValue());
                        valueList.add(productAttrValuePO);
                    }
                }
                productAttrPO.setProductAttrValueList(valueList);
                if (attr.isSpec()) {
                    specAttrs.add(productAttrPO);
                } else {
                    noSpecAttrs.add(productAttrPO);
                }
                attrs.add(productAttrPO);
            }
        }
        // 遍历已设置的属性集合，如果当前商户已经不支持其中的某个属性，便将其去除
        Iterator<ProductAttrPO> iterator = specAttrs.iterator();
        while (iterator.hasNext()) {
            ProductAttrPO po = iterator.next();
            if (!attrUuids2.contains(po.getTemplateAttrUuid())) {
                iterator.remove();
            }
        }
        Iterator<ProductAttrPO> iterator2 = noSpecAttrs.iterator();
        while (iterator2.hasNext()) {
            ProductAttrPO po = iterator2.next();
            if (!attrUuids2.contains(po.getTemplateAttrUuid())) {
                iterator2.remove();
            }
        }
        Iterator<ProductAttrPO> iterator3 = attrs.iterator();
        while (iterator3.hasNext()) {
            ProductAttrPO po = iterator3.next();
            if (!attrUuids2.contains(po.getTemplateAttrUuid())) {
                iterator3.remove();
            }
        }
        List<ProductImagePO> imageList = productImageService.getImagesByMainUuid(uuid);
        Collections.sort(attrs, new Comparator<ProductAttrPO>() {
            @Override
            public int compare(ProductAttrPO o1, ProductAttrPO o2) {
                int spec1 = o1.isSpec() ? 1 : 0;
                int spec2 = o2.isSpec() ? 1 : 0;
                return spec2 - spec1;
            }
        });
        productMainPO.setProductAttrList(attrs);
        productMainPO.setProductSpecAttrList(specAttrs);
        productMainPO.setProductNoSpecAttrList(noSpecAttrs);
        productMainPO.setProductImageList(imageList);
        ProductCategoryPO productCategoryPO = productCategoryService.getByUuid(productMainPO.getCategoryUuid());
        if (null != productCategoryPO) {
            productMainPO.setCategoryName(productCategoryPO.getName());
        }
        return productMainPO;
    }

    /**
     * 同步商品信息到ES
     *
     * @param qm
     */
    //@Scheduled(initialDelay = 60000, fixedRate = 300000)
    @Override
    public void syncProductToES(QueryMessageDTO qm) {
        logger.info("***** 同步商品到ES 开始 *****");
        List<ProductMainPO> list = getProductInfoList(qm);
        if (null != list && list.size() > 0) {
            productRepository.syncToElastic(list);
            logger.info("同步 {} 条商品数据......", list.size());
        }
        logger.info("***** 同步商品到ES 完成 *****");
    }

    /**
     * 从ES删除商品信息
     *
     * @param idList
     */
    @Override
    public void deleteProductFromES(List<String> idList) {
        if (null != idList && idList.size() > 0) {
            productRepository.deleteProductFromES(idList);
        }
    }

    @Override
    public List<ProductMainPO> getProductInfoList(QueryMessageDTO qm) {
        List<ProductMainPO> list = queryByCondition(qm);
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> products = list.stream().map(ProductMainPO::getUuid).collect(Collectors.toList());
            //获取商品的月销数量
            Map<String, Integer> monthSellMap = orderMainService.getMonthSellNum(products);
            for (ProductMainPO po : list) {
                VendorPO vendorPO = vendorService.getByUuid(po.getVendorUuid());
                po.setVendorName(vendorPO.getVendorName());
                ProductCategoryPO categoryPO = productCategoryService.getByUuid(po.getCategoryUuid());
                po.setCategoryName(categoryPO.getName());
                List<ProductImagePO> imageList = productImageService.getImagesByMainUuid(po.getUuid());
                if (null != imageList && imageList.size() > 0) {
                    po.setSmallimg(imageList.get(0).getSmallImg());
                    po.setBigimg(imageList.get(0).getBigImg());
                }
                if (MapUtils.isNotEmpty(monthSellMap)) {
                    int monthSell = monthSellMap.get(po.getUuid()) == null ? 0 : monthSellMap.get(po.getUuid());
                    po.setMonthSell(monthSell);
                }
                //查询关联的属性
                List<ProductAttrPO> attrList = productAttrService.getAttrsByMainUuid(po.getUuid());
                if (CollectionUtils.isNotEmpty(attrList)) {
                    //获取所有的属性值uuid
                    List<String> attrValueList = attrList.stream().flatMap(productAttrValueList -> productAttrValueList.getProductAttrValueList().stream()).map(v -> v.getUuid()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(attrValueList)) {
                        po.setAttrValueUuids(JSON.toJSONString(attrValueList));
                    }
                }
                //将商品的规格属性集合，设置到po中
                po.setProductAttrList(attrList);
            }
        }
        return list;
    }

    @Override
    public List<ProductMainPO> getProductInfoFromES(QueryMessageDTO qm) {
        return productRepository.getProductInfoFromES(qm, qm.isByPage());
    }

    @Override
    public int getCountFromES(QueryMessageDTO qm) {
        return productRepository.getCountFromES(qm);
    }

    @Override
    public void saveProduct(ProductMainPO productMainPO) {
        // 1. 保存菜品主信息
        productRepository.create(productMainPO);
        // 2. 保存菜品规格信息  暂时废弃
        //saveSpecs(productMainPO);
        // 3. 保存菜品的属性
        saveAttrs(productMainPO);
        // 4. 保存菜品的图片
        saveImages(productMainPO);
        // 5. 同步商品到ES

    }

    @Override
    public void updateProduct(ProductMainPO productMainPO) {
        // 1.更新菜品主信息
        productRepository.update(productMainPO);
        // 2.删除原来的规格信息  暂时废弃
        // productSpecService.deleteByMainUuid(productMainPO.getUuid());
        //saveSpecs(productMainPO);
        // 3.删除原来的非规格属性以及属性值
        productAttrService.deleteByMainUuid(productMainPO.getUuid());
        saveAttrs(productMainPO);
        // 4.删除原来的图片数据，重新插入
        productImageService.deleteByMainUuid(productMainPO.getUuid());
        saveImages(productMainPO);

    }

    /**
     * 保存商品图片信息
     *
     * @param productMainPO
     */
    private void saveImages(ProductMainPO productMainPO) {
        List<ProductImagePO> productImageList = productMainPO.getProductImageList();
        if (null != productImageList) {
            for (ProductImagePO productImage : productImageList) {
                productImage.setProductUuid(productMainPO.getUuid());
                productImageService.create(productImage);
            }
        }
    }

    /**
     * 保存商品属性信息(包括规格和非规格属性)
     *
     * @param productMainPO
     */
    private void saveAttrs(ProductMainPO productMainPO) {
        List<ProductAttrPO> productAttrList = productMainPO.getProductAttrList();
        if (null != productAttrList) {
            for (ProductAttrPO productAttr : productAttrList) {
                productAttr.setProductUuid(productMainPO.getUuid());
                productAttrService.create(productAttr);
                List<ProductAttrValuePO> valueList = productAttr.getProductAttrValueList();
                for (ProductAttrValuePO value : valueList) {
                    value.setAttrUuid(productAttr.getUuid());
                    // 如果是非规格属性,则将价格设置为菜品的基本价
                    if (!productAttr.isSpec()) {
                        value.setPrice(productMainPO.getPrice());
                    }
                    productAttrValueService.create(value);
                }
            }
        }
    }

    /**
     * 保存商品规格（暂废弃）
     *
     * @param productMainPO
     */
    private void saveSpecs(ProductMainPO productMainPO) {
        List<ProductSpecPO> productSpecList = productMainPO.getProductSpecList();
        if (null != productSpecList) {
            for (ProductSpecPO productSpec : productSpecList) {
                productSpec.setProductUuid(productMainPO.getUuid());
                productSpecService.create(productSpec);
            }
        }
    }

    @Override
    public void deleteProducts(List<String> idList) {
        // 1. 根据商品uuids查询属性uuids
        List<String> attrUuids = productAttrService.getUuidsByMainUuids(idList);
        // 2. 根据属性uuids删除属性值记录
        if (!attrUuids.isEmpty()) {
            productAttrValueService.deleteByAttrUuids(attrUuids);
            // 3.根据属性uuids删除属性记录
            productAttrService.deletes(attrUuids);
        }
        // 4. 根据商品uuids删除规格记录 暂时废弃
        //productSpecService.deleteByMainUuids(idList);
        // 5. 根据商品uuids删除图片记录
        productImageService.deleteByMainUuids(idList);
        // 6. 根据商品uuids删除商品信息
        productRepository.deletes(idList);
    }

    @Override
    public void syncToElastic(List<ProductMainPO> list) {
        productRepository.syncToElastic(list);
    }

    @Override
    public List<ProductCategoryPO> getAllProductsByVendorUuid(String vendorUuid) {
        QueryMessageDTO qm1 = new QueryMessageDTO();
        qm1.setByPage(false);
        qm1.addCondition("vendorUuid", "EQ", vendorUuid);
        List<ProductCategoryPO> cateList = productCategoryService.queryFromES(qm1);
        for (ProductCategoryPO cate : cateList) {
            String categoryUuid = cate.getUuid();
            List<ProductMainPO> productList = new ArrayList<>();
            QueryMessageDTO qm2 = new QueryMessageDTO();
            qm2.setByPage(false);
            qm2.addCondition("categoryUuid", "EQ", categoryUuid);
            productList = getProductInfoFromES(qm2);
            cate.setProductList(productList);
        }
        return cateList;
    }


    /**
     * 供前台首页使用，查询招牌和优惠标签的商品，以及商户所有商品
     *
     * @param vendorUuid
     * @param showSign
     * @param showPromotion
     * @return
     */
    @Override
    public List<ProductCategoryPO> getAllProducts(String vendorUuid, Boolean showSign, Boolean showPromotion) {
        List<ProductCategoryPO> cateList = new ArrayList<>();

        //如果显示招牌商品，构造招牌分类和商品数据结构
        QueryMessageDTO qm1 = new QueryMessageDTO();
        // 指定不分页
        qm1.setByPage(false);
        qm1.addCondition("vendorUuid", "EQ", vendorUuid);
        if (showSign) {
            ProductCategoryPO cate = new ProductCategoryPO();
            cate.setUuid("zp");
            cate.setName("招牌");
            //获取招牌下的商品
            qm1.addCondition("tag", "EQ", "zp");
            qm1.addCondition("state", "EQ", true);
            cate.setProductList(getProductInfoFromES(qm1));
            cateList.add(cate);
        }

        //如果显示优惠商品，构造优惠分类和商品数据结构
        QueryMessageDTO qm2 = new QueryMessageDTO();
        qm2.setByPage(false);
        qm2.addCondition("vendorUuid", "EQ", vendorUuid);
        if (showPromotion) {
            ProductCategoryPO cate = new ProductCategoryPO();
            cate.setUuid("yh");
            cate.setName("优惠");
            //获取优惠下的商品
            qm2.addCondition("tag", "EQ", "");
            qm2.addCondition("promotionType", "NE", "0");
            qm2.addCondition("state", "EQ", true);
            cate.setProductList(getProductInfoFromES(qm2));
            cateList.add(cate);
        }

        //获取商户的分类（后面会调整成从es获取）
        QueryMessageDTO qm3 = new QueryMessageDTO();
        qm3.setByPage(false);
        qm3.addCondition("vendorUuid", "EQ", vendorUuid);
        List<ProductCategoryPO> categorys = productCategoryService.queryFromES(qm3);
        if (CollectionUtils.isNotEmpty(categorys)) {
            //遍历分类，从es获取商品
            QueryMessageDTO qm4 = new QueryMessageDTO();
            qm4.setByPage(false);
            for (ProductCategoryPO cate : categorys) {
                qm4.addCondition("categoryUuid", "EQ", cate.getUuid());
                cate.setProductList(getProductInfoFromES(qm4));
                cateList.add(cate);
            }
        }
        return cateList;
    }
}
